﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Data.Linq;
using System.Text;
using BusinessObjects;
using BusinessObjects.Constants;
using DataEntities;
using DataProvider;
using SQLDataProvider;

namespace BusinessServices
{
    public class ChuZuService
    {
        private readonly IBaseRepository<ChuZuInfo> _chuZuRepository;
        private readonly IBaseRepository<XuZuInfo> _xuZuRepository;

        public ChuZuService()
        {
            _chuZuRepository = new BaseRepository<ChuZuInfo>();
            _xuZuRepository = new BaseRepository<XuZuInfo>();
        }

        /// <summary>
        /// 获取所有出租单
        /// </summary>
        /// <returns>出租单列表</returns>
        public List<ChuZuInfo> GetAll()
        {
            return _chuZuRepository.GetAll(o => true, JoinKeHuAndCarAndXuZu);
        }

        /// <summary>
        /// 获取指定客户的出租信息
        /// </summary>
        /// <param name="keHuId">客户编辑</param>
        /// <returns>出租单列表</returns>
        public List<ChuZuInfo> GetChuZuInfoByKeHuId(int keHuId)
        {
            return _chuZuRepository.GetAll(o => o.iKeHuId == keHuId, JoinKeHuAndCarAndXuZu);
        }

        /// <summary>
        /// 获取所有有效出租单
        /// </summary>
        /// <returns>出租单列表</returns>
        public List<ChuZuInfo> GetActiveChuZuInfo()
        {
            return _chuZuRepository.GetAll(o => !o.bCZZF, JoinKeHuAndCarAndXuZu);
        }

        /// <summary>
        /// 根据用户Id获取活动中的出租单 
        /// </summary>
        /// <param name="keHuId">客户编号</param>
        public ChuZuInfo GetActiveChuZuInfoByKeHuId(int keHuId)
        {
            return _chuZuRepository.Get(o => !o.bCZZF && o.iKeHuId == keHuId, JoinKeHuAndCarAndXuZu);
        }

        //Join 车辆信息表和客户信息表
        private DataLoadOptions JoinKeHuAndCarAndXuZu()
        {
            var loadOption = new DataLoadOptions();
            loadOption.LoadWith<ChuZuInfo>(o => o.CarInfo);
            loadOption.LoadWith<ChuZuInfo>(o => o.KeHuInfo);
            loadOption.LoadWith<ChuZuInfo>(o => o.XuZuInfo);
            return loadOption;
        }

        /// <summary>
        /// 获取已到期的出租单
        /// </summary>
        public List<ChuZuInfo> GetTimeOutChuZuInfo()
        {
            return _chuZuRepository.GetAll(o => !o.bCZZF && (o.bXZ ? o.XuZuInfo.Max(x => x.tNewDate) <= DateTime.Now : o.tEndDate <= DateTime.Now));
        }

        /// <summary>
        /// 获取未到期的出租单
        /// </summary>
        public List<ChuZuInfo> GetNotTimeOutChuZuInfo()
        {
            return _chuZuRepository.GetAll(o => !o.bCZZF && (o.bXZ ? o.XuZuInfo.Max(x => x.tNewDate) > DateTime.Now : o.tEndDate > DateTime.Now));
        }

        /// <summary>
        /// 获取租出车辆Id
        /// </summary>
        public List<int> GetZuChuCarIds()
        {
            return _chuZuRepository.Get(o => o.iCarid, o => !o.bCZZF);
        }

        /// <summary>
        /// 根据用户Id获取简要出租信息
        /// </summary>
        /// <param name="keHuId">用户Id</param>
        public SimpleInfoContract GetSimpleChuZuInfoByKeHuId(int keHuId)
        {
            return GetSimpleChuZuInfo(o => o.iKeHuId == keHuId);
        }

        /// <summary>
        /// 根据车辆Id获取简要出租信息
        /// </summary>
        /// <param name="carId">车辆Id</param>
        public SimpleInfoContract GetSimpleChuZuInfoByCarId(int carId)
        {
            return GetSimpleChuZuInfo(o => o.iCarid == carId);
        }

        #region 获取并构建出租信息
        private SimpleInfoContract GetSimpleChuZuInfo(Func<ChuZuInfo, bool> condition)
        {
            var chuZuInfo = _chuZuRepository.GetAll(condition, JoinCarInfo);
            var result = new SimpleInfoContract();
            var strBuilder = new StringBuilder();

            chuZuInfo.ForEach(leaseInfo => GenerateStr(leaseInfo, ref strBuilder));
            result.Count = chuZuInfo.Count;
            result.Content = strBuilder.Length == 0 ? Constants.NoChuZuInfo : strBuilder.ToString();
            return result;
        }

        //Join车辆信息表
        private DataLoadOptions JoinCarInfo()
        {
            var loadOption = new DataLoadOptions();
            loadOption.LoadWith<ChuZuInfo>(o => o.CarInfo);
            return loadOption;
        }

        //创建简要信息内容
        private void GenerateStr(ChuZuInfo cz, ref StringBuilder strBuilder)
        {
            var days = (cz.tEndDate - cz.tStartDate).Days;
            strBuilder.AppendFormat(Constants.SimpleChuZuInfo, cz.CarInfo.sCType, cz.tEndDate,
                days, cz.dRiFuJE, cz.dRiFuJE * days, cz.bCZZF ? "已还车" : "使用中");
        }
        #endregion

        /// <summary>
        /// 获取已超期并未还车的信息条数
        /// </summary>
        /// <returns></returns>
        public int CountTimeOverChuZuInfo()
        {
            var overTimeIds = _chuZuRepository.Get(o => o.iCZDId, o => o.tEndDate < DateTime.Now && !o.bCZZF);
            var xuZuOverTimeCount = _xuZuRepository.Count(o => overTimeIds.Contains(o.iCZDId) && o.tNewDate < DateTime.Now && !o.bXZZF);
            return overTimeIds.Count + xuZuOverTimeCount;
        }

        /// <summary>
        /// 获取已到期并未还车的信息条数
        /// </summary>
        public int CountTimeOutChuZuInfo()
        {
            var expiredIds = _chuZuRepository.Get(o => o.iCZDId, o => o.tEndDate == DateTime.Now && !o.bCZZF);
            var xuZuExpiredCount = _xuZuRepository.Count(o => expiredIds.Contains(o.iCZDId) && o.tNewDate == DateTime.Now && !o.bXZZF);
            return expiredIds.Count + xuZuExpiredCount;
        }

        /// <summary>
        /// 添加一条租出信息
        /// </summary>
        public ChuZuInfo Add(ChuZuInfo chuZuInfo)
        {
            return _chuZuRepository.Add(chuZuInfo);
        }

        /// <summary>
        /// 更新租出信息
        /// </summary>
        /// <param name="chuZuId">出租单编号</param>
        /// <param name="update">包含更新的委托，在此委托中进行数据更改操作</param>
        public ChuZuInfo Update(int chuZuId, Action<ChuZuInfo> update)
        {
            return _chuZuRepository.Update(c => c.iCZDId == chuZuId, update);
        }
    }
}
